package com.zhss.designpattern.builder;

/**
 * @author fanwei
 * @desc 普通构造者方法
 *        好处：1.通过builder接口将复杂构建步骤拆分成了多个部分，代码逻辑清晰，维护性和扩展性都很好
 *              2.将对象构建的过程，封装在了director里面，director来基于builder进行构建，构建逻辑修改，不需要修改很多地方
 *              3.相对于工厂，有一个很好的抽象设计，director和builder
 */
public class BuilderPatternDemo {

    public static void main(String[] args) {
        Director director = new Director(new ConcreteBuilder());
        Product product = director.create("abc","aa","cc");

        System.out.println(product);
    }

    interface Builder{
        void field1(String val1);
        void field2(String val2);
        void field3(String val3);
        Product create();
    }

    static class ConcreteBuilder implements Builder{

        private Product product = new Product();

        public void field1(String val1) {
            product.setVal1(val1);
            System.out.println("val1 is :"+val1);
        }

        public void field2(String val2) {
            product.setVal2(val2);
            System.out.println("val2 is :"+val2);
        }

        public void field3(String val3) {
            product.setVal3(val3);
            System.out.println("val3 is :"+val3);
        }

        public Product create() {
            return product;
        }
    }

    static class Product{
        private String val1;
        private String val2;
        private String val3;

        public String getVal1() {
            return val1;
        }

        public void setVal1(String val1) {
            this.val1 = val1;
        }

        public String getVal2() {
            return val2;
        }

        public void setVal2(String val2) {
            this.val2 = val2;
        }

        public String getVal3() {
            return val3;
        }

        public void setVal3(String val3) {
            this.val3 = val3;
        }

        @Override
        public String toString() {
            return "Product{" +
                    "val1='" + val1 + '\'' +
                    ", val2='" + val2 + '\'' +
                    ", val3='" + val3 + '\'' +
                    '}';
        }
    }

    /**
     * director是面向builder的接口，来编程的
     * director可以复杂控制构建的一个步骤，具体的每个步骤的逻辑封装在具体的builder类中
     * 如果我们此时要更换一整套的构建逻辑，可以再搞一个新的builder类就可以了
     * 但是我们的整个构建步骤是没有任何改变的
     *
     * 如果整个构建步骤变化了，但是对构建的逻辑是没有影响的
     *
     * @author fanwei
     *
     */
    static class Director{
        private Builder builder;

        public Director(Builder builder) {
            this.builder = builder;
        }

        public Product create(String val1,String val2,String val3){
            builder.field1(val1);
            builder.field2(val2);
            builder.field3(val3);
            return builder.create();
        }

        public Product create(String val1){
            builder.field1(val1);
            return builder.create();
        }
    }
}
